package com.yunhe.authority.repository.authority;

import com.yunhe.authority.domain.authority.Menu;
import com.yunhe.authority.domain.authority.Role;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * 菜单数据仓库
 * @desc 菜单数据仓库定义
 * @author liuronglei
 */
@Repository
public interface MenuRepository extends Neo4jRepository<Menu, Long> {
    /**
     * 获得所有可用菜单列表
     */
    @Query("MATCH (n:Menu) WHERE not ()-[:HAS_CHILD]->(n) WITH n MATCH p=(n)-[*0..1]->(m) WHERE n.activity=true RETURN p, ID(n)")
    Iterable<Menu> findMenusByActivity();

    /**
     * 根据角色ID获得绑定菜单列表（无父子级别）
     * @param roleId 角色ID
     */
    @Query("start role=node({roleId}) match (role)-[:HAS_MENU]->(menus:Menu) return menus order by menus.topTime desc")
    Iterable<Menu> findMenusByRoleId(@Param("roleId") Long roleId);

    @Query("start role=node({roleId}) match(role)-[:HAS_OPTIONAL_MENU]->(menus) return menus")
    Iterable<Menu> findHasMenusByRoleId(@Param("roleId") Long roleId);

    @Query("start role=node({roleId}) match(role)-[:HAS_MENU_APP]->(menus:Menu) return menus")
    Iterable<Menu> findAppMenusByRoleId(@Param("roleId") Long roleId);

    @Query("start role=node({roleId}) match(role)-[:HAS_OPTIONAL_MENU_APP]->(menus) return menus")
    Iterable<Menu> findHasAppMenusByRoleId(@Param("roleId") Long roleId);

    /**
     * 根据用户ID获得绑定的所有菜单列表
     * @param userId 用户ID
     * @param firmCode 单位代码
     */
    @Query("start user=node({userId}) match (user)-[:HAS_ROLE]->(role:Role{activity:1})-[:HAS_MENU]->(n) " +
            "match (f:Firm{code:{firmCode},activity:true})-[:HAS_MENU]->(m) where n.activity=true and m=n return m,n")
    Iterable<Menu> findMenusByUserId(@Param("firmCode") Long firmCode, @Param("userId") Long userId);

    /**
     * 根据用户ID获得绑定的所有菜单列表
     * @param userId 用户ID
     * @param firmCode 单位代码
     */
    @Query("start user=node({userId}) match (user)-[:HAS_ROLE]->(role:Role{activity:1})-[:HAS_MENU_APP]->(n) " +
            "match (f:Firm{code:{firmCode},activity:true})-[:HAS_MENU_APP]->(m) where n.activity=true and m=n return m,n")
    Iterable<Menu> findAppMenusByUserId(@Param("firmCode") Long firmCode, @Param("userId") Long userId);

    /**
     * 根据菜单编号获得菜单对象
     * @param name 菜单编号
     */
    Menu findByName(String name);

    /**
     * 根据菜单ID获得子菜单列表
     * @param menuId 菜单ID
     */
    @Query("match (m:Menu)-[:HAS_CHILD]->(n) where ID(m)={menuId} return n order by n.sn")
    Iterable<Menu> findChildren(@Param("menuId") Long menuId);

    /**
     * 添加父子菜单关系
     * @param parentId 父菜单ID
     * @param childId 子菜单ID
     */
    @Query("start parent=node({parentId}),child=node({childId}) create (parent)-[:HAS_CHILD]->(child)")
    void addChildRelation(@Param("parentId") Long parentId, @Param("childId") Long childId);

    /**
     * 删除父子菜单关系
     * @param childId 子菜单ID
     */
    @Query("start child=node({childId}) match ()-[r:HAS_CHILD]->(child) delete r")
    void delChildRelation(@Param("childId") Long childId);

    /**
     * 根据单位ID获得绑定的所有菜单列表 （无父子级别）
     * @param firmId 单位ID
     */
    @Query("start firm=node({firmId}) match (firm)-[:HAS_MENU]->(menus) return menus order by menus.topTime desc")
    Iterable<Menu> findMenusByFirmId(@Param("firmId") Long firmId);

    /**************************20210223新增*****************************/

    /**
     * 根据项目ID获得绑定的所有菜单列表
     * @param stationId 项目代码
     */
    @Query("match (s:Station)-[:HAS_MENU{stationId:{stationId}}]->(m:Menu) return m order by m.topTime desc")
    Iterable<Menu> findMenusByStationId(@Param("stationId") Long stationId);

    /**
     * 根据项目ID获得绑定的所有菜单列表
     * @param stationId 项目代码
     * @param systemMenuCategory 使用平台
     */
    @Query("match (s:Station)-[:HAS_MENU{stationId:{stationId}}]->(m:Menu) where m.systemMenuCategory={systemMenuCategory} return m order by m.topTime desc")
    Iterable<Menu> findMenusByStationIdAndSystemMenuCategory(@Param("stationId") Long stationId, @Param("systemMenuCategory") String systemMenuCategory);

    /**
     * 添加菜单与项目绑定关系
     * @param id 菜单ID
     * @param stationId 项目ID
     */
    @Query("start station=node({stationId}),menu=node({id}) create (station)-[r:HAS_MENU{stationId:{stationId}}]->(menu)")
    void menusBindByStationId(@Param("id") Long id, @Param("stationId") Long stationId);

    /**
     * 删除菜单与项目的关系（解绑）
     * @param stationId 项目ID
     * @param systemMenuCategory
     */
    @Query("match (s:Station)-[r:HAS_MENU{stationId:{stationId}}]->(m:Menu) where m.systemMenuCategory = {systemMenuCategory} delete r")
    void menusUnbindByStationId(@Param("stationId") Long stationId,@Param("systemMenuCategory") String systemMenuCategory);

    /**
     * 根据系统查询菜单列表
     * @param systemMenuCategory 系统编号
     * @return Iterable
     */
    @Query("match (m:Menu) where m.systemMenuCategory={systemMenuCategory} return m order by m.topTime desc")
    Iterable<Menu> findBySystemMenuCategory(String systemMenuCategory);

    /****************************企业菜单******************************/

    /**
     * 根据企业id查询菜单列表
     * @param companyId 企业id
     * @return Iterable<Menu>
     */
    @Query("match (c:Company)-[:HAS_MENU]->(m:Menu) where id(c)={companyId} return m order by m.topTime desc")
    Iterable<Menu> findMenusByCompanyId(@Param("companyId") Long companyId);

    /**
     * 根据企业id绑定菜单
     * @param companyId 企业id
     * @param id 菜单id
     */
    @Query("start company=node({companyId}),menu=node({id}) create (company)-[r:HAS_MENU]->(menu)")
    void menusBindCompany(@Param("companyId") Long companyId, @Param("id") Long id);

    /**
     * 企业解绑菜单
     * @param companyId 企业id
     */
    @Query("match (c:Company)-[r:HAS_MENU]->(m:Menu) where id(c)={companyId} and m.systemMenuCategory={systemMenuCategory} delete r ")
    void menusUnbindCompany(@Param("companyId") Long companyId,@Param("systemMenuCategory") String systemMenuCategory);

    /**
     * @Description 园区解绑菜单时查询绑定角色
     * @Param Long stationId
     * @Return List<Role>
     * @Date 2021/8/17 14:55
     */
    @Query("match (s:Station)-[hr:HAS_ROLE]->(r:Role)-[hm:HAS_MENU]->(m:Menu) where ID(s)={stationId} and ID(m)={id} return r")
    List<Role> getRoleByStation(@Param("id") Long id, @Param("stationId") Long stationId);

    @Query("match (s:Station)-[hr:HAS_ROLE]->(r:Role)-[hm:HAS_MENU]->(m:Menu) where ID(s)={stationId} and ID(m)={id} delete hm")
    void menusUnBindByStationIdAndMenuId(@Param("stationId") Long stationId,@Param("id") Long id);
}